﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;

namespace WpfGenetic.Tests
{
    public static class Parsing
    {
        public static void ParseBigramTest()
        {
            // Получаем данные о точности
            var pathFull = "FullLog.txt";

            var dataFull = File.ReadAllText(pathFull);

            var buffer1 = dataFull.Split('\n').Where(txt => txt.Length > 2 && txt[0] == ' ' && txt[1] == 'P').ToList();
            var buffer2 = buffer1.Select(txt => txt.Remove(0, 6)).ToList();
            var buffer3 = buffer2.Select(txt => txt.Remove(txt.Length - 1)).ToList();

            List<List<double>> dDataPer = [];

            foreach ( var b in buffer3)
            {
                dDataPer.Add(ToDoubleList(("" + b).Split(", ").ToList()));
            }

            // Получаем данные о времени
            var pathTime = "PopulationLog.txt";

            var dataTime = File.ReadAllText(pathTime);

            buffer1 = dataTime.Split('\n').Where(txt => txt.Length > 5 && txt.Remove(5) == " maxT").ToList();
            buffer2 = buffer1.Select(txt => txt.Remove(0, 9)).ToList();
            buffer3 = buffer2.Select(txt => txt.Remove(txt.Length - 1)).ToList();

            List<List<double>> dDataMax = [];

            foreach (var b in buffer3)
            {
                dDataMax.Add(ToDoubleList(("" + b).Split(", ").ToList()));
            }

            buffer1 = dataTime.Split('\n').Where(txt => txt.Length > 5 && txt.Remove(5) == " minT").ToList();
            buffer2 = buffer1.Select(txt => txt.Remove(0, 9)).ToList();
            buffer3 = buffer2.Select(txt => txt.Remove(txt.Length - 1)).ToList();

            List<List<double>> dDataMin = [];

            foreach (var b in buffer3)
            {
                dDataMin.Add(ToDoubleList(("" + b).Split(", ").ToList()));
            }

            // Варианты максимума поколений
            List<int> generationList = new() { 500, 1000, 1500, 2000, 2500, 3000 };
            // Варианты размера популяции
            List<int> populationList = new() { 1000, 1500, 2000, 2500, 3000, 3500 };

            // Пороговое значение 
            double threshold = 0.95;
            List<double> thresholdList;

            int dataIndex = 0;
            int timeIndex = 0;

            double cnt;

            foreach ( var pop in populationList)
            {
                thresholdList = [];

                foreach ( var gen in generationList)
                {
                    cnt = 0;

                    foreach (var d in dDataPer[dataIndex])
                    {
                        if ( d > threshold)
                        {
                            cnt++;
                        }
                    }

                    thresholdList.Add(Double.Round(cnt / dDataPer[dataIndex].Count, 2) * 100);

                    dataIndex++;
                }

                //CreateGenerationPlot(thresholdList, generationList, pop);
                CreateGenerationPlotWithTime(thresholdList, dDataMax[timeIndex], dDataMin[timeIndex], generationList, pop);

                timeIndex++;
            }

        }

        // Создание графика процента совпадений для коллекции разного кол-ва поколений без времени
        private static void CreateGenerationPlotWithTime(List<double> YDataPerformance, List<double> YDataMaxTime, List<double> YDataMinTime, List<int> XDataGeneration, int pop)
        {
            ScottPlot.Plot plot = new();
            plot.Axes.Bottom.Label.Text = "Количество поколений";

            // Точность совпадения
            var percentScatter = plot.Add.Scatter(XDataGeneration, YDataPerformance);
            percentScatter.Axes.XAxis = plot.Axes.Bottom;
            percentScatter.Axes.YAxis = plot.Axes.Left;

            percentScatter.Color = ScottPlot.Color.FromHex("#008CF9"); // Синий
            percentScatter.MarkerShape = ScottPlot.MarkerShape.FilledDiamond;
            percentScatter.MarkerColor = percentScatter.Color;
            percentScatter.MarkerSize = 10;
            percentScatter.LegendText = "Рез.";

            plot.Axes.Left.Label.Text = "Результативность (%)";
            plot.Axes.Left.Label.ForeColor = percentScatter.Color;

            // Максимумы
            var yAxisTime = plot.Axes.AddLeftAxis();
            var MaxScatter = plot.Add.Scatter(XDataGeneration, YDataMaxTime);
            MaxScatter.Axes.XAxis = plot.Axes.Bottom;
            MaxScatter.Axes.YAxis = yAxisTime;

            MaxScatter.Color = ScottPlot.Color.FromHex("#FFA900"); // Желтый
            MaxScatter.MarkerShape = ScottPlot.MarkerShape.Asterisk;
            MaxScatter.MarkerColor = MaxScatter.Color;
            MaxScatter.MarkerSize = 10;
            MaxScatter.LegendText = "Макс.";

            // Минимумы
            var MinScatter = plot.Add.Scatter(XDataGeneration, YDataMinTime);
            MinScatter.Axes.XAxis = plot.Axes.Bottom;
            MinScatter.Axes.YAxis = yAxisTime;

            MinScatter.Color = ScottPlot.Color.FromHex("#EBAC23"); // Желтый
            MinScatter.MarkerShape = ScottPlot.MarkerShape.OpenCircle;
            MinScatter.MarkerColor = MinScatter.Color;
            MinScatter.MarkerSize = 10;
            MinScatter.LegendText = "Мин.";

            yAxisTime.LabelText = "Время (сек.)";
            yAxisTime.LabelFontColor = MinScatter.Color;

            plot.Title($"Популяция {pop} особей");
            plot.SavePng($"PerformanceBigrams/Pop{pop}withTime.png", 700, 500);
        }


        // Создание графика процента совпадений для коллекции разного кол-ва поколений без времени
        private static void CreateGenerationPlot(List<double> YDataPerformance, List<int> XDataGeneration, int pop)
        {
            ScottPlot.Plot plot = new();
            plot.Axes.Bottom.Label.Text = "Количество поколений";

            // Точность совпадения
            var percentScatter = plot.Add.Scatter(XDataGeneration, YDataPerformance);
            percentScatter.Axes.XAxis = plot.Axes.Bottom;
            percentScatter.Axes.YAxis = plot.Axes.Left;
            plot.Axes.Left.Label.Text = "Результативность";

            plot.Title($"Популяция {pop} особей");
            plot.SavePng($"PerformanceBigrams/Pop{pop}.png", 700, 500);
        }

        public static List<double> ToDoubleList(List<string> list)
        {
            var doubles = new List<double>();

            foreach (string s in list)
            {
                if (double.TryParse(s, out double d))
                {
                    doubles.Add(d);
                }
            }
            return doubles;
        }
    }
}
